Last Updated: December 19, 2025
An Online Stock Exchange is a digital platform where investors can trade stocks and other financial instruments electronically. It serves as a marketplace that brings together buyers and sellers, facilitates order matching, and ensures smooth execution of trades in real time.
Apple Inc.
Alphabet Inc.
Microsoft Corp.
Amazon.com Inc.
Tesla Inc.
NVIDIA Corp.
JPMorgan Chase
Visa Inc.
Modern stock exchanges also provide:
In this chapter, we will explore the low-level design of an online stock exchange system in detail.
Lets start by clarifying the requirements:
Before starting the design, it's important to ask thoughtful questions to uncover hidden assumptions and better define the scope of the system.
Here is an example of how a conversation between the candidate and the interviewer might unfold:
Candidate: What types of orders should the system support? Just basic market and limit orders, or more complex types like stop-loss or fill-or-kill?
Interviewer: For this design, let's stick to Market and Limit orders for both buying and selling.
Candidate: Should the system handle user accounts, including cash balances and stock portfolios?
Interviewer: Yes, each user must have an account that tracks their cash balance and the quantity of each stock they own. The system must ensure that a user has sufficient funds to buy or enough stock to sell.
Candidate: Should we support multiple stocks being traded simultaneously, or focus on a single stock for simplicity?
Interviewer: Multiple stocks should be supported.
Candidate: How should the order matching engine work? Should it follow a price-time priority (first come, first served at the same price), or is simple price priority sufficient?
Interviewer: Let's keep the matching logic simple. The engine should match the highest bid (buy order) with the lowest ask (sell order) as long as the bid is greater than or equal to the ask. We can ignore the time priority aspect for now.
Candidate: Do we need to notify users of events like when a trade executes or when a stock's price changes?
Interviewer: A user should be notified about status changes to their own orders (e.g., OPEN -> FILLED). It would also be great if users could "subscribe" to specific stocks and get notified when their prices change.
After gathering the details, we can summarize the key system requirements.
Core entities are the fundamental building blocks of our system. We identify them by analyzing key nouns (e.g., user, stock, order, order book, trade) and actions (e.g., place, match, cancel, publish, view) from the functional requirements. These typically translate directly into classes, enums, or interfaces in an object-oriented design.
Let’s walk through the functional requirements and extract the relevant entities:
This points to a User entity as the primary actor. Each User has an Account, which is responsible for managing their cash balance and a portfolio of owned stocks. The stocks themselves are represented by a Stock entity, which includes a symbol and a market price.
An Order is a central entity representing a user's intent to trade. Key attributes like OrderType (MARKET, LIMIT), TransactionType (BUY, SELL), and OrderStatus (OPEN, FILLED) are best represented by Enums.
The core matching logic is encapsulated in a StockExchange entity. This class acts as the central marketplace, holding the order books for all stocks. It is implemented as a Singleton to ensure there is only one exchange in the system.
To hide the complexity of the underlying components (matching engine, state transitions, command execution), a StockBrokerageSystem class is introduced. It acts as a Facade and Singleton, providing a unified entry point for all client interactions.
These core entities define the essential abstractions of an online stock exchange and will guide the structure of your low-level design and class diagrams.
This section breaks down the system's architecture into its fundamental classes, their responsibilities, and the relationships that connect them. We also explore the key design patterns that provide robustness and flexibility to the solution.
OrderType: Distinguishes between MARKET and LIMIT orders.TransactionType: Indicates whether an order is a BUY or SELL transaction.OrderStatus: Tracks the lifecycle of an order (OPEN, FILLED, CANCELLED).AccountA thread-safe class that holds a user's cash balance and their portfolio of stocks.
It provides synchronized methods for debiting/crediting funds and adding/removing stocks.
StockRepresents a publicly traded stock.
It holds the stock's symbol and its current market price. It also acts as the Subject in the Observer pattern, maintaining a list of observers to notify upon price changes.
UserRepresents a client of the brokerage.
It holds an Account and acts as a concrete Observer by implementing StockObserver to receive real-time price notifications. It also has a method to receive order status updates.
OrderA central class representing a single trade request.
It contains all details of the order, including the user, stock, type, and quantity. It acts as the Context for the State pattern, delegating cancellation logic to its currentState object.
StockExchange (Singleton)The core engine of the system.
It maintains the order books (buy and sell orders) and contains the matching logic to execute trades when buy and sell orders align.
StockBrokerageSystem (Singleton & Facade)The primary entry point for the application.
It hides the system's internal complexity from the client and provides a simple, unified API for all major operations like registering users and placing orders.
The relationships between classes define the system's structure and data flow.
User "has-an" Account. The Account's lifecycle is managed by the User.Order is associated with one User and one Stock.Order is associated with an ExecutionStrategy to determine its execution condition.Order has a current OrderState.Stock (Subject) is associated with a list of StockObservers (which are Users).User implements the StockObserver interface.BuyStockCommand and SellStockCommand implement the OrderCommand interface.OpenState, etc.) implement the OrderState interface.MarketOrderStrategy, etc.) implement the ExecutionStrategy interface.StockBrokerageSystem (Facade) depends on OrderCommand objects to place orders.OrderCommands depend on the StockExchange to submit the orders.OrderBuilder to construct an Order object.StockExchange depends on the ExecutionStrategy of an order to check if a trade can be made.The ExecutionStrategy allows the logic for executing different order types (Market, Limit) to be encapsulated and made interchangeable.
The StockExchange can check if an order is executable without knowing the specific rules of that order type.
The lifecycle of an Order is managed using the State pattern. The Order (Context) delegates actions like cancel() to its current OrderState object.
This cleanly separates state-specific logic (e.g., you can't cancel a Filled order) and makes the system robust.
This pattern is used to notify users of stock price changes. The Stock object (Subject) notifies all subscribed Users (Observers) whenever its price is updated, enabling real-time updates.
The OrderCommand interface and its implementations (BuyStockCommand, SellStockCommand) encapsulate a request as an object.
This decouples the client that initiates an order from the object that knows how to perform it (the StockExchange).
The OrderBuilder provides a fluent API for constructing complex Order objects. This is ideal for an object with multiple parameters, improving readability and ensuring that orders are created in a valid state.
The StockBrokerageSystem class serves as a facade. It provides a simple, high-level API (registerUser, placeBuyOrder) that hides the complex internal workflows involving accounts, order books, and the matching engine.
StockBrokerageSystem and StockExchange are implemented as singletons. This ensures a single, globally accessible point of control for the entire application and for the central order book, preventing state inconsistencies.
1class OrderType(Enum):
2 MARKET = "MARKET"
3 LIMIT = "LIMIT"
4
5class TransactionType(Enum):
6 BUY = "BUY"
7 SELL = "SELL"
8
9class OrderStatus(Enum):
10 OPEN = "OPEN"
11 PARTIALLY_FILLED = "PARTIALLY_FILLED"
12 FILLED = "FILLED"
13 CANCELLED = "CANCELLED"
14 FAILED = "FAILED"OrderType distinguishes between market and limit orders.TransactionType indicates whether the action is a buy or sell.OrderStatus tracks the lifecycle of an order.1class InsufficientFundsException(Exception):
2 def __init__(self, message: str):
3 super().__init__(message)
4
5class InsufficientStockException(Exception):
6 def __init__(self, message: str):
7 super().__init__(message)These exceptions are thrown during trade validations:
InsufficientFundsException: not enough cash to buy.InsufficientStockException: not enough stock to sell.1class Account:
2 def __init__(self, initial_cash: float):
3 self.balance = initial_cash
4 self.portfolio: Dict[str, int] = {} # Stock symbol -> quantity
5 self.lock = threading.Lock()
6
7 def debit(self, amount: float) -> None:
8 with self.lock:
9 if self.balance < amount:
10 raise InsufficientFundsException(f"Insufficient funds to debit {amount}")
11 self.balance -= amount
12
13 def credit(self, amount: float) -> None:
14 with self.lock:
15 self.balance += amount
16
17 def add_stock(self, symbol: str, quantity: int) -> None:
18 with self.lock:
19 self.portfolio[symbol] = self.portfolio.get(symbol, 0) + quantity
20
21 def remove_stock(self, symbol: str, quantity: int) -> None:
22 with self.lock:
23 current_quantity = self.portfolio.get(symbol, 0)
24 if current_quantity < quantity:
25 raise InsufficientStockException(f"Not enough {symbol} stock to sell.")
26 self.portfolio[symbol] = current_quantity - quantity
27
28 def get_balance(self) -> float:
29 return self.balance
30
31 def get_portfolio(self) -> Dict[str, int]:
32 return self.portfolio.copy()
33
34 def get_stock_quantity(self, symbol: str) -> int:
35 return self.portfolio.get(symbol, 0)The Account class holds the user's cash balance and owned stocks. All operations are thread-safe via synchronized to ensure consistency in concurrent environments.
Implements the Observer Pattern. Users are notified when stock prices change.
1class StockObserver(ABC):
2 @abstractmethod
3 def update(self, stock: 'Stock') -> None:
4 pass1class Stock:
2 def __init__(self, symbol: str, initial_price: float):
3 self.symbol = symbol
4 self.price = initial_price
5 self.observers: List[StockObserver] = []
6
7 def get_symbol(self) -> str:
8 return self.symbol
9
10 def get_price(self) -> float:
11 return self.price
12
13 def set_price(self, new_price: float) -> None:
14 if self.price != new_price:
15 self.price = new_price
16 self._notify_observers()
17
18 def add_observer(self, observer: StockObserver) -> None:
19 self.observers.append(observer)
20
21 def remove_observer(self, observer: StockObserver) -> None:
22 if observer in self.observers:
23 self.observers.remove(observer)
24
25 def _notify_observers(self) -> None:
26 for observer in self.observers:
27 observer.update(self)Each User holds an Account and receives stock price and order status updates. Acts as an observer of stock price changes.
1class User(StockObserver):
2 def __init__(self, name: str, initial_cash: float):
3 self.user_id = str(uuid.uuid4())
4 self.name = name
5 self.account = Account(initial_cash)
6
7 def get_user_id(self) -> str:
8 return self.user_id
9
10 def get_name(self) -> str:
11 return self.name
12
13 def get_account(self) -> Account:
14 return self.account
15
16 def update(self, stock: Stock) -> None:
17 print(f"[Notification for {self.name}] Stock {stock.get_symbol()} price updated to: ${stock.get_price():.2f}")
18
19 def order_status_update(self, order: 'Order') -> None:
20 print(f"[Order Notification for {self.name}] Order {order.get_order_id()} for {order.get_stock().get_symbol()} is now {order.get_status().value}.")
21Uses the State Pattern to allow state-specific behavior for cancel().
1class Order:
2 def __init__(self, order_id: str, user: User, stock: Stock, order_type: OrderType,
3 quantity: int, price: float, execution_strategy: ExecutionStrategy, owner: User):
4 self.order_id = order_id
5 self.user = user
6 self.stock = stock
7 self.type = order_type
8 self.quantity = quantity
9 self.price = price # Limit price for Limit orders
10 self.execution_strategy = execution_strategy
11 self.owner = owner
12 self.current_state = OpenState() # Initial state
13 self.status = OrderStatus.OPEN
14
15 def cancel(self) -> None:
16 self.current_state.cancel(self)
17
18 def get_order_id(self) -> str:
19 return self.order_id
20
21 def get_user(self) -> User:
22 return self.user
23
24 def get_stock(self) -> Stock:
25 return self.stock
26
27 def get_type(self) -> OrderType:
28 return self.type
29
30 def get_quantity(self) -> int:
31 return self.quantity
32
33 def get_price(self) -> float:
34 return self.price
35
36 def get_status(self) -> OrderStatus:
37 return self.status
38
39 def get_execution_strategy(self) -> ExecutionStrategy:
40 return self.execution_strategy
41
42 def set_state(self, state: OrderState) -> None:
43 self.current_state = state
44
45 def set_status(self, status: OrderStatus) -> None:
46 self.status = status
47 self._notify_owner()
48
49 def _notify_owner(self) -> None:
50 if self.owner:
51 self.owner.order_status_update(self)Provides a fluent API to construct complex Order objects step-by-step.
1class OrderBuilder:
2 def __init__(self):
3 self.user: Optional[User] = None
4 self.stock: Optional[Stock] = None
5 self.type: Optional[OrderType] = None
6 self.transaction_type: Optional[TransactionType] = None
7 self.quantity: int = 0
8 self.price: float = 0.0
9
10 def for_user(self, user: User) -> 'OrderBuilder':
11 self.user = user
12 return self
13
14 def with_stock(self, stock: Stock) -> 'OrderBuilder':
15 self.stock = stock
16 return self
17
18 def buy(self, quantity: int) -> 'OrderBuilder':
19 self.transaction_type = TransactionType.BUY
20 self.quantity = quantity
21 return self
22
23 def sell(self, quantity: int) -> 'OrderBuilder':
24 self.transaction_type = TransactionType.SELL
25 self.quantity = quantity
26 return self
27
28 def at_market_price(self) -> 'OrderBuilder':
29 self.type = OrderType.MARKET
30 self.price = 0 # Not needed for market order
31 return self
32
33 def with_limit(self, limit_price: float) -> 'OrderBuilder':
34 self.type = OrderType.LIMIT
35 self.price = limit_price
36 return self
37
38 def build(self) -> Order:
39 execution_strategy = MarketOrderStrategy() if self.type == OrderType.MARKET else LimitOrderStrategy(self.transaction_type)
40 return Order(
41 str(uuid.uuid4()),
42 self.user,
43 self.stock,
44 self.type,
45 self.quantity,
46 self.price,
47 execution_strategy,
48 self.user
49 )Encapsulates buy/sell operations using the Command Pattern to decouple order placement from the execution logic.
1class OrderCommand(ABC):
2 @abstractmethod
3 def execute(self) -> None:
4 pass
5
6class BuyStockCommand(OrderCommand):
7 def __init__(self, account: Account, order: Order):
8 self.account = account
9 self.order = order
10 self.stock_exchange = StockExchange.get_instance()
11
12 def execute(self) -> None:
13 # For market order, we can't pre-check funds perfectly.
14 # For limit order, we can pre-authorize the amount.
15 estimated_cost = self.order.get_quantity() * self.order.get_price()
16 if self.order.get_type() == OrderType.LIMIT and self.account.get_balance() < estimated_cost:
17 raise InsufficientFundsException("Not enough cash to place limit buy order.")
18 print(f"Placing BUY order {self.order.get_order_id()} for {self.order.get_quantity()} shares of {self.order.get_stock().get_symbol()}.")
19 self.stock_exchange.place_buy_order(self.order)
20
21class SellStockCommand(OrderCommand):
22 def __init__(self, account: Account, order: Order):
23 self.account = account
24 self.order = order
25 self.stock_exchange = StockExchange.get_instance()
26
27 def execute(self) -> None:
28 if self.account.get_stock_quantity(self.order.get_stock().get_symbol()) < self.order.get_quantity():
29 raise InsufficientStockException("Not enough stock to place sell order.")
30 print(f"Placing SELL order {self.order.get_order_id()} for {self.order.get_quantity()} shares of {self.order.get_stock().get_symbol()}.")
31 self.stock_exchange.place_sell_order(self.order)Implements the State Pattern for each valid OrderStatus, restricting transitions (e.g., filled orders can't be cancelled).
1class OrderState(ABC):
2 @abstractmethod
3 def handle(self, order: 'Order') -> None:
4 pass
5
6 @abstractmethod
7 def cancel(self, order: 'Order') -> None:
8 pass
9
10class OpenState(OrderState):
11 def handle(self, order: 'Order') -> None:
12 print("Order is open and waiting for execution.")
13
14 def cancel(self, order: 'Order') -> None:
15 order.set_status(OrderStatus.CANCELLED)
16 order.set_state(CancelledState())
17 print(f"Order {order.get_order_id()} has been cancelled.")
18
19class FilledState(OrderState):
20 def handle(self, order: 'Order') -> None:
21 print("Order is already filled.")
22
23 def cancel(self, order: 'Order') -> None:
24 print("Cannot cancel a filled order.")
25
26class CancelledState(OrderState):
27 def handle(self, order: 'Order') -> None:
28 print("Order is cancelled.")
29
30 def cancel(self, order: 'Order') -> None:
31 print("Order is already cancelled.")Encapsulates different execution rules using the Strategy Pattern. This cleanly separates decision logic for market vs. limit orders.
1class ExecutionStrategy(ABC):
2 @abstractmethod
3 def can_execute(self, order: 'Order', market_price: float) -> bool:
4 pass
5
6class LimitOrderStrategy(ExecutionStrategy):
7 def __init__(self, transaction_type: TransactionType):
8 self.type = transaction_type
9
10 def can_execute(self, order: 'Order', market_price: float) -> bool:
11 if self.type == TransactionType.BUY:
12 # Buy if market price is less than or equal to limit price
13 return market_price <= order.get_price()
14 else: # SELL
15 # Sell if market price is greater than or equal to limit price
16 return market_price >= order.get_price()
17
18class MarketOrderStrategy(ExecutionStrategy):
19 def can_execute(self, order: 'Order', market_price: float) -> bool:
20 return True # Market orders can always executeImplements the order matching engine. Supports atomic trade execution and uses synchronized blocks to ensure consistency.
1class StockExchange:
2 _instance: Optional['StockExchange'] = None
3 _lock = threading.Lock()
4
5 def __new__(cls):
6 if cls._instance is None:
7 with cls._lock:
8 if cls._instance is None:
9 cls._instance = super().__new__(cls)
10 return cls._instance
11
12 def __init__(self):
13 if hasattr(self, 'initialized'):
14 return
15 self.buy_orders: Dict[str, List[Order]] = defaultdict(list)
16 self.sell_orders: Dict[str, List[Order]] = defaultdict(list)
17 self.match_lock = threading.Lock()
18 self.initialized = True
19
20 @classmethod
21 def get_instance(cls) -> 'StockExchange':
22 return cls()
23
24 def place_buy_order(self, order: Order) -> None:
25 self.buy_orders[order.get_stock().get_symbol()].append(order)
26 self._match_orders(order.get_stock())
27
28 def place_sell_order(self, order: Order) -> None:
29 self.sell_orders[order.get_stock().get_symbol()].append(order)
30 self._match_orders(order.get_stock())
31
32 def _match_orders(self, stock: Stock) -> None:
33 with self.match_lock: # Critical section to prevent race conditions during matching
34 buys = self.buy_orders.get(stock.get_symbol(), [])
35 sells = self.sell_orders.get(stock.get_symbol(), [])
36
37 if not buys or not sells:
38 return
39
40 match_found = True
41 while match_found:
42 match_found = False
43 best_buy = self._find_best_buy(buys)
44 best_sell = self._find_best_sell(sells)
45
46 if best_buy and best_sell:
47 buy_price = stock.get_price() if best_buy.get_type() == OrderType.MARKET else best_buy.get_price()
48 sell_price = stock.get_price() if best_sell.get_type() == OrderType.MARKET else best_sell.get_price()
49
50 if buy_price >= sell_price:
51 self._execute_trade(best_buy, best_sell, sell_price) # Trade at the seller's asking price
52 match_found = True
53
54 def _execute_trade(self, buy_order: Order, sell_order: Order, trade_price: float) -> None:
55 print(f"--- Executing Trade for {buy_order.get_stock().get_symbol()} at ${trade_price:.2f} ---")
56
57 buyer = buy_order.get_user()
58 seller = sell_order.get_user()
59
60 trade_quantity = min(buy_order.get_quantity(), sell_order.get_quantity())
61 total_cost = trade_quantity * trade_price
62
63 # Perform transaction
64 buyer.get_account().debit(total_cost)
65 buyer.get_account().add_stock(buy_order.get_stock().get_symbol(), trade_quantity)
66
67 seller.get_account().credit(total_cost)
68 seller.get_account().remove_stock(sell_order.get_stock().get_symbol(), trade_quantity)
69
70 # Update orders
71 self._update_order_status(buy_order, trade_quantity)
72 self._update_order_status(sell_order, trade_quantity)
73
74 # Update stock's market price to last traded price
75 buy_order.get_stock().set_price(trade_price)
76
77 print("--- Trade Complete ---")
78
79 def _update_order_status(self, order: Order, quantity_traded: int) -> None:
80 # This is a simplified update logic. A real system would handle partial fills.
81 order.set_status(OrderStatus.FILLED)
82 order.set_state(FilledState())
83 stock_symbol = order.get_stock().get_symbol()
84
85 # Remove from books
86 if order in self.buy_orders[stock_symbol]:
87 self.buy_orders[stock_symbol].remove(order)
88 if order in self.sell_orders[stock_symbol]:
89 self.sell_orders[stock_symbol].remove(order)
90
91 def _find_best_buy(self, buys: List[Order]) -> Optional[Order]:
92 open_orders = [o for o in buys if o.get_status() == OrderStatus.OPEN]
93 if not open_orders:
94 return None
95 return max(open_orders, key=lambda o: o.get_price()) # Highest limit price is best
96
97 def _find_best_sell(self, sells: List[Order]) -> Optional[Order]:
98 open_orders = [o for o in sells if o.get_status() == OrderStatus.OPEN]
99 if not open_orders:
100 return None
101 return min(open_orders, key=lambda o: o.get_price()) # Lowest limit price is bestActs as a Facade for the entire brokerage system. Encapsulates user registration, stock management, and order processing.
1class StockBrokerageSystem:
2 _instance: Optional['StockBrokerageSystem'] = None
3 _lock = threading.Lock()
4
5 def __new__(cls):
6 if cls._instance is None:
7 with cls._lock:
8 if cls._instance is None:
9 cls._instance = super().__new__(cls)
10 return cls._instance
11
12 def __init__(self):
13 if hasattr(self, 'initialized'):
14 return
15 self.users: Dict[str, User] = {}
16 self.stocks: Dict[str, Stock] = {}
17 self.initialized = True
18
19 @classmethod
20 def get_instance(cls) -> 'StockBrokerageSystem':
21 return cls()
22
23 def register_user(self, name: str, initial_amount: float) -> User:
24 user = User(name, initial_amount)
25 self.users[user.get_user_id()] = user
26 return user
27
28 def add_stock(self, symbol: str, initial_price: float) -> Stock:
29 stock = Stock(symbol, initial_price)
30 self.stocks[stock.get_symbol()] = stock
31 return stock
32
33 def place_buy_order(self, order: Order) -> None:
34 user = order.get_user()
35 command = BuyStockCommand(user.get_account(), order)
36 command.execute()
37
38 def place_sell_order(self, order: Order) -> None:
39 user = order.get_user()
40 command = SellStockCommand(user.get_account(), order)
41 command.execute()
42
43 def cancel_order(self, order: Order) -> None:
44 order.cancel()The demo class simulates user actions to validate the system.
1def print_account_status(user: User) -> None:
2 print(f"Member: {user.get_name()}, Cash: ${user.get_account().get_balance():.2f}, Portfolio: {user.get_account().get_portfolio()}")
3
4def stock_brokerage_system_demo():
5 # System Setup
6 system = StockBrokerageSystem.get_instance()
7
8 # Create Stocks
9 apple = system.add_stock("AAPL", 150.00)
10 google = system.add_stock("GOOG", 2800.00)
11
12 # Create Members (Users)
13 alice = system.register_user("Alice", 20000.00)
14 bob = system.register_user("Bob", 25000.00)
15
16 # Bob already owns some Apple stock
17 bob.get_account().add_stock("AAPL", 50)
18
19 # Members subscribe to stock notifications (Observer Pattern)
20 apple.add_observer(alice)
21 google.add_observer(alice)
22 apple.add_observer(bob)
23
24 print("--- Initial State ---")
25 print_account_status(alice)
26 print_account_status(bob)
27
28 print("\n--- Trading Simulation Starts ---\n")
29
30 # SCENARIO 1: Limit Order Match
31 print("--- SCENARIO 1: Alice places a limit buy, Bob places a limit sell that matches ---")
32
33 # Alice wants to buy 10 shares of AAPL if the price is $150.50 or less
34 alice_buy_order = OrderBuilder() \
35 .for_user(alice) \
36 .buy(10) \
37 .with_stock(apple) \
38 .with_limit(150.50) \
39 .build()
40 system.place_buy_order(alice_buy_order)
41
42 # Bob wants to sell 20 of his shares if the price is $150.50 or more
43 bob_sell_order = OrderBuilder() \
44 .for_user(bob) \
45 .sell(20) \
46 .with_stock(apple) \
47 .with_limit(150.50) \
48 .build()
49 system.place_sell_order(bob_sell_order)
50
51 # The exchange will automatically match and execute this trade.
52 # Let's check the status after the trade.
53 time.sleep(0.1) # Give time for notifications to print
54 print("\n--- Account Status After Trade 1 ---")
55 print_account_status(alice)
56 print_account_status(bob)
57
58 # SCENARIO 2: Price Update triggers notifications
59 print("\n--- SCENARIO 2: Market price of GOOG changes ---")
60 google.set_price(2850.00) # Alice will get a notification
61
62 # SCENARIO 3: Order Cancellation (State Pattern)
63 print("\n--- SCENARIO 3: Alice places an order and then cancels it ---")
64 alice_cancel_order = OrderBuilder() \
65 .for_user(alice) \
66 .buy(5) \
67 .with_stock(google) \
68 .with_limit(2700.00) \
69 .build() # Price is too low, so it won't execute immediately
70 system.place_buy_order(alice_cancel_order)
71
72 print(f"Order status before cancellation: {alice_cancel_order.get_status().value}")
73 system.cancel_order(alice_cancel_order)
74 print(f"Order status after cancellation attempt: {alice_cancel_order.get_status().value}")
75
76 # Now try to cancel an already filled order
77 print("\n--- Trying to cancel an already FILLED order (State Pattern) ---")
78 print(f"Bob's sell order status: {bob_sell_order.get_status().value}")
79 system.cancel_order(bob_sell_order) # This should fail
80 print(f"Bob's sell order status after cancel attempt: {bob_sell_order.get_status().value}")
81
82
83if __name__ == "__main__":
84 stock_brokerage_system_demo()Which entity is responsible for matching buy and sell orders in the online stock exchange design?
No comments yet. Be the first to comment!